// --------------------------------------------------------------------------------------------------------------------
// <copyright file="WeakHashMap.cs" company="JDML Consulting Ltd.">
//   Copyright 2011 Photon Project - http://photon.codeplex.com
// </copyright>
// <summary>
//   WeakHashMap
// </summary>
// --------------------------------------------------------------------------------------------------------------------

namespace Photon.Collections
{
    using System;

    public class WeakHashMap<TKey, TValue> : HashMap<TKey, TValue> 
      where TKey : class 
      where TValue : class
   {
      #region WeakHashMapEntry

      protected class WeakHashMapEntry : Entry
      {
         private readonly WeakReference _keyReference;
         private readonly WeakReference _valueReference;

         /// <summary>
         /// Initializes a new instance of the <see cref="WeakHashMap&lt;TKey, TValue&gt;.WeakHashMapEntry"/> class.
         /// </summary>
         /// <param name="key">The key.</param>
         /// <param name="value">The value.</param>
         public WeakHashMapEntry(TKey key, TValue value)
         {
            _keyReference = new WeakReference(key);
            _valueReference = new WeakReference(value);
         }
         
         /// <summary>
         /// Gets the key for the entry.
         /// </summary>
         public override TKey Key
         {
            get
            {
               return (TKey)_keyReference.Target;
            }
         }

         /// <summary>
         /// Gets or sets the value contained by the entry.
         /// </summary>
         /// <remarks>
         /// The value is tracked via a weak reference.
         /// </remarks>
         public override TValue Value
         {
            get
            {
               return (TValue)_valueReference.Target;
            }
            set
            {
               _valueReference.Target = value;
            }
         }

         /// <summary>
         /// Gets a value indicating whether this instance is alive.
         /// </summary>
         /// <value><c>true</c> if this instance is alive; otherwise, <c>false</c>.</value>
         public override bool IsAlive
         {
             get
             {
                 return _valueReference.IsAlive && _keyReference.IsAlive;
             }
         }
      }

      #endregion

      protected override void OnResize()
      {
         var enumerator = new Enumerator(this);
         while (enumerator.MoveNext())
         {
             if (!enumerator.Current.IsAlive)
             {
                 enumerator.RemoveCurrent();
             }
         }
      }

      protected override Entry NewEntry(TKey key, TValue value)
      {
         return new WeakHashMapEntry(key, value);
      }
   }
}